﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using Game.Classes;
using System.Drawing.Imaging;

namespace Game.Klassen
{
    //Basisklasse für alle Hintergrundobjekte
    abstract class BackGroundObject
    {
        //Basisklasse um HIntergrundobjekte zu erstellen
        public Image image;
        public Point position;
        public Size  size;
        public Point offset;
        public bool  enabled;

        public int animateIndex;
        public int animFrames;

        public abstract void    AnimateTick();
        public abstract void    Update();
        public abstract Image   getImage();
    }

    //Luftblasen Hintergrundobjekt
    class Bubble : BackGroundObject
    {
        #region Initialisieren
        //Eigenschaften
        String  movement;
        int     direction;
        int     movecount;
        bool    repeat;

        //Konstruktoren
        public Bubble(Point pos, Size size)
        {
            //Werte setzen
            this.image      = Game.Properties.Resources.bubble;
            this.position   = pos;
            this.size       = size;
            this.movecount  = 0;
            this.enabled    = true;
            this.offset     = new Point(0, 0);
            this.repeat     = false;

            //Zufällige auswahl der Bewegungsrichtung
            direction = Session.rand.Next(0, 3);
            if (direction == 1)
                movement = "left";
            else
                movement = "right";
        }

        public Bubble(Point pos, Size size, Point offset)
        {
            //Werte setzen
            this.image = Game.Properties.Resources.bubble;
            this.position = pos;
            this.size = size;
            this.movecount = 0;
            this.enabled = true;
            this.offset = offset;
            this.repeat = false;

            //Zufällige auswahl der Bewegungsrichtung
            direction = Session.rand.Next(0, 3);
            if (direction == 1)
                movement = "left";
            else
                movement = "right";
        }

        public Bubble(Point pos, Size size, bool repeat, string direction)
        {
            //Werte setzen
            this.image      = Game.Properties.Resources.bubble;
            this.position   = pos;
            this.size       = size;
            this.movecount  = 0;
            this.enabled    = true;
            this.offset     = new Point(0, 0);
            this.repeat     = repeat;
            this.movement   = direction;
        }
        #endregion

        #region Tools

        //ObjektBild zurückgeben
        public override Image getImage()
        {
            return this.image;
        }

        //Blase ausschalten oder an Startposition setzen
        private void checkDeactivateOrReset()
        {
            if (repeat)
            {
                if (position.Y + offset.Y < 0 - size.Height * 2)
                {
                    offset = new Point(0, 0);
                    position = new Point(this.position.X, 800);
                }
            }
            else
            {
                if (position.Y * 64 + offset.Y < 0 - this.size.Height)
                    this.enabled = false;
            }
        }

        //Blasen leicht hin und her Bewegen lassen
        private void shake()
        {
            if (movement == "left")
                if (movecount > -5)
                {
                    offset.X -= 2;
                    movecount--;
                }
                else
                    movement = "right";
            else if (movement == "right")
                if (movecount < 5)
                {
                    offset.X += 2;
                    movecount++;
                }
                else
                    movement = "left";
        }

        //Keine Animation
        public override void AnimateTick()
        { }
        #endregion

        //Updatemethode
        public override void Update()
        {
            if (enabled)
            {
                //Blasen aufsteigen lassen
                offset.Y -= 2;

                //Blase zerstören wenn Sie oben angekommen ist oder wiederholen
                checkDeactivateOrReset(); 

                //Blasen leicht hin und her Bewegen lassen
                shake();
            }
        }
    }

    //Schlüssel als Hintergrundobjekt
    class Key : BackGroundObject
    {
        #region Initialisieren
        //Konstruktor
        public Key(Point pos, Size size)
        {
            this.position       = pos;
            this.size           = size;
            this.image          = Game.Properties.Resources.key;
            this.enabled        = true;
            this.offset         = new Point(Session.rand.Next(0, 10), Session.rand.Next(0, 10));

            this.animateIndex   = 0;
            this.animFrames     = image.Width / 64 - 1;
        }
        #endregion

        #region Tools
        //Bild zurückgeben
        public override Image getImage()
        {
            return Tools.cropImage(new Rectangle((animateIndex * 64), 0, 64, 64), image);
        }

        //Keine Animation
        public override void AnimateTick()
        {
            if (animateIndex + 1 <= animFrames)
                animateIndex++;
            else
                animateIndex = 0;
        }
        #endregion

        //Prüfen ob Schlüssel vom Spieler aufgehoben werden kann
        public override void Update()
        {
            
            if (enabled)
            {
                foreach(Player p in Session.players)
                    if (p.pos == position)
                        if (!p.hasKey)
                        {
                            p.hasKey = true;
                            Session.setMessage("Schlüssel aufgehoben. Finde die Truhe!");
                            enabled  = false;
                        }
            }
        }
    }

    //Truhe hintergrundobjekt
    class Chest : BackGroundObject
    {
        #region Initialisieren
        //Konstruktor
        public Chest(Point pos, Size size)
        {
            this.position = pos;
            this.size = size;
            this.image = Game.Properties.Resources.Truhe;
            this.enabled = true;
            this.offset = new Point(2, 2);

            this.animateIndex   = 0;
            this.animFrames     = image.Width / 64 - 1;
        }
        #endregion

        #region Tools

        //Bild zurückgeben
        public override Image getImage()
        {
            return Tools.cropImage(new Rectangle((animateIndex * 64), 0, 64, 64), image);
        }

        public override void AnimateTick()
        {
            if (animateIndex + 1 <= animFrames)
                animateIndex++;
            else
                animateIndex = 0;
        }
        #endregion

        //Prüfen ob Spieler Schlüssel hat und an der Truhe steht
        public override void Update()
        {
            if (enabled)
            {
                foreach (Player p in Session.players)
                    if (p.pos == position)
                        if (p.hasKey)
                        {
                            enabled = false;
                            Session.state = "ende";
                            if(Session.soundEnabled)
                                Session.fenster.playWinMusic();
                        }
            }
        }
    }

    //O2 Flasche hintergrundobjekt
    class OxygenTank : BackGroundObject
    {
        #region Initialisieren
        //Konstruktor
        public OxygenTank(Point pos, Size size)
        {
            this.position   = pos;
            this.size       = size;
            this.image      = Game.Properties.Resources.flasche_item;
            this.enabled    = true;
            this.offset     = new Point(0, 0);

            this.animateIndex   = 0;
            this.animFrames     = image.Width / 64 - 1;
        }
        #endregion

        #region Tools

        //Bild zurückgeben
        public override Image getImage()
        {
            return Tools.cropImage(new Rectangle((animateIndex * 64), 0, 64, 64), image);
        }

        
        public override void AnimateTick()
        {
            if (animateIndex + 1 <= animFrames)
                animateIndex++;
            else
                animateIndex = 0;
        }

        #endregion

        //Prüfen ob Spieler auf FLasche steht
        public override void Update()
        {
            if (enabled)
            {
                foreach (Player p in Session.players)
                    if (p.pos == position)
                    {
                        int oxy = Session.rand.Next(3, 10);
                        p.addOxygen(oxy);
                        Session.setMessage("Du erhälst "+oxy+" Sauerstoff");
                        enabled = false;
                    }
            }
        }
    }

    //Helium Flasche hintergrundobjekt
    class HeTank : BackGroundObject
    {
        #region Initialisieren
        //Konstruktor
        public HeTank(Point pos, Size size)
        {
            this.position = pos;
            this.size = size;
            this.image = Game.Properties.Resources.flascheHE;
            this.enabled = true;
            this.offset = new Point(0, 0);

            this.animateIndex = 0;
            this.animFrames = image.Width / 64 - 1;
        }
        #endregion

        #region Tools

        //Bild zurückgeben
        public override Image getImage()
        {
            return Tools.cropImage(new Rectangle((animateIndex * 64), 0, 64, 64), image);
        }


        public override void AnimateTick()
        {
            if (animateIndex + 1 <= animFrames)
                animateIndex++;
            else
                animateIndex = 0;
        }

        #endregion

        //Prüfen ob Spieler auf FLasche steht
        public override void Update()
        {
            if (enabled)
            {
                foreach (Player p in Session.players)
                    if (p.pos == position)
                    {
                        p.move("up", false, true);
                        Session.setMessage("Das Helium lässt dich aufsteigen!");
                        enabled = false;
                    }
            }
        }
    }

    //Pflanze hintergrundobjekt
    class Plant : BackGroundObject
    {
        #region Initialisieren
        //Konstruktor
        public Plant(Point pos, Size size)
        {
            this.position = pos;
            this.size = size;
            this.image = Game.Properties.Resources.pflanze;
            this.enabled = true;
            this.offset = new Point(0, 0);

            this.animateIndex = 0;
            this.animFrames = image.Width / 64 - 1;
        }
        #endregion

        #region Tools

        //Bild zurückgeben
        public override Image getImage()
        {
            return Tools.cropImage(new Rectangle((animateIndex * 64), 0, 64, 64), image);
        }


        public override void AnimateTick()
        {
            if (animateIndex + 1 <= animFrames)
                animateIndex++;
            else
                animateIndex = 0;
        }

        #endregion

        //Prüfen ob Spieler auf Pflanze steht
        public override void Update()
        {
            if (enabled)
            {
                foreach (Player p in Session.players)
                    if (p.pos == position)
                    {
                        p.stopMoving = true;
                        Session.setMessage("Die Pflanzen blockieren deinen Motor.");
                        enabled = false;
                    }
            }
        }
    }

    //Co2 Flasche hintergrundobjekt
    class CO2Tank : BackGroundObject
    {
        #region Initialisieren
        //Konstruktor
        public CO2Tank(Point pos, Size size)
        {
            this.position = pos;
            this.size = size;
            this.image = Game.Properties.Resources.flaschec02;
            this.enabled = true;
            this.offset = new Point(0, 0);

            this.animateIndex   = 0;
            this.animFrames     = image.Width / 64 - 1;
        }
        #endregion

        #region Tools

        //Bild zurückgeben
        public override Image getImage()
        {
            return Tools.cropImage(new Rectangle((animateIndex * 64), 0, 64, 64), image);
        }


        public override void AnimateTick()
        {
            if (animateIndex + 1 <= animFrames)
                animateIndex++;
            else
                animateIndex = 0;
        }

        #endregion

        //Prüfen ob Spieler Schlüssel hat und an der Truhe steht
        public override void Update()
        {
            if (enabled)
            {
                foreach (Player p in Session.players)
                    if (p.pos == position)
                    {
                        p.remOxygen(5);
                        Session.setMessage("Du verlierst 5 Sauerstoff");
                        enabled = false;
                    }
            }
        }
    }

    //Studel hintergrundobjekt
    class Whirl : BackGroundObject
    {
        #region Initialisieren
        //Konstruktor
        public Whirl(Point pos, Size size)
        {
            this.position = pos;
            this.size = size;
            this.image = Game.Properties.Resources.strudel;
            this.enabled = true;
            this.offset = new Point(0, 0);

            this.animateIndex = 0;
            this.animFrames = image.Width / 64 - 1;
        }
        #endregion

        #region Tools

        //Bild zurückgeben
        public override Image getImage()
        {
            return Tools.cropImage(new Rectangle((animateIndex * 64), 0, 64, 64), image);
        }


        public override void AnimateTick()
        {
            if (animateIndex + 1 <= animFrames)
                animateIndex++;
            else
                animateIndex = 0;
        }

        #endregion

        //Prüfen ob Spieler Schlüssel hat und an der Truhe steht
        public override void Update()
        {
            if (enabled)
            {
                foreach (Player p in Session.players)
                    if (p.pos == position)
                    {
                        //Zufälligen Spieler Suchen
                        int randPlayer = Session.rand.Next(0, Session.players.Count);

                        while (Session.currentPlayer == Session.players[randPlayer])
                        {
                            randPlayer = Session.rand.Next(0, Session.players.Count);
                        }

                        //Spieler 1 Position Speichern
                        Point curPos = Session.currentPlayer.pos;

                        //Spieler Positionen tauschen 
                        //Session.currentPlayer.animateTimer.Stop();
                        Session.currentPlayer.pos = Session.players[randPlayer].pos;
                        Session.players[randPlayer].pos = curPos;

                        //Benachrichtigen
                        Session.setMessage(Session.currentPlayer.name + " tauscht Position mit " + Session.players[randPlayer].name);
                        
                        //Powerup deaktivieren und Schleife Abbrechen!
                        enabled = false;
                        break;
                    }
            }
        }
    }

    //Animiertes HintergrundObjekt
    class AnimatedObject : BackGroundObject
    {
        //Konstruktor
        public AnimatedObject(Point pos, Size size)
        {
            this.position   = pos;
            this.size       = size;
            this.enabled    = true;
            this.offset     = new Point(0, 0);
            this.image      = Game.Properties.Resources.fish;

            this.animFrames     = image.Width/64 - 1;
            this.animateIndex   = 0;
        }


        //Animationsframe weiterschalten
        public override void AnimateTick()
        {
            if (animateIndex + 1 <= animFrames)
                animateIndex++;
            else
                animateIndex = 0;
        }

        //Update wird hier nicht benötigt
        public override void Update()
        {}

        //Aktuelles Bild für Animation zurückgeben
        public override Image getImage()
        {
            return Tools.cropImage(new Rectangle((animateIndex * 64), 0, 64, 64), image);
        }
    }
}


